#登录相关

from django.urls import reverse
from django.http import JsonResponse
from django_redis import get_redis_connection
from django.shortcuts import render,HttpResponse,redirect


from web import models
from django.conf import settings

from utils.reponse import BaseResponse
from utils.code import get_code,send_sms
from web.forms import account_form


#登录函数
def login(request):
    #请求方式为GET 返回界面
    if request.method == "GET":
        form = account_form.LoginForm()
        return render(request,"login.html",{"form":form})
    '''
    1、否则为POST取值 
    2、会收到键 'csrfmiddlewaretoken' 它由 HTML 表单的 {% csrf_token %} 产生，产生的值是随机的 不写会报错；
    Django 要求我们加入一个 csrfmiddlewaretoken（会产生一个隐藏input标签，在cookies里面 与 提交到后台都有，产生的值由中间件验证）
    '''
    #需要验证输入的用户名，密码是否为空 Form方法
    form = account_form.LoginForm(data=request.POST) #把用户提交的数据给到LoginForm 自动验证是否为空

    # 开始校验 如果失败 form返回输入的原值 客户输入的值不丢失
    if not form.is_valid():
        print("所有单个字段校验错误的值",form.errors.get("password")) #所有校验错误的值
        print("clean整体字段校验错误的值", form.non_field_errors())
        return render(request, "login.html", {"form": form}) #输入错误记得返回form

    #否则Form校验成功
    data_dict = form.cleaned_data
    print(data_dict)  # 校验成功 返回 用户输入的值{'username'：admin，'password'：123}
    #删除role 以后 剩余username password 通过解包的方式 **data_dict 传给数据库 注意form字段必须等于数据库字段
    role = data_dict.pop('role')#收到的角色类型 用户2 还是 管理员1,选中不同数据库的表
    print(role,data_dict)
    #角色映射,方便后期在settings.py文件中的权限读取
    mappings = {"1":"ADMIN","2":"CUSTOMER"}
    if role not in mappings.keys():
        form.add_error("role", "角色不存在") #错误加在下拉框下面
        #用户类型选择失败 记得返回form 否则HTML界面找不到
        return render(request, "login.html",{"error":"角色不存在","form":form})
    #取值后校验是否正确(去数据库校验)
    if role == "1": #管理员
        #查找数据库数据，激活、账户，密码  first()取到对象
        uesr_object = models.Administrator.objects.filter(active = 1).filter(**data_dict).first()
    elif role == "2": #用户
        uesr_object = models.Customer.objects.filter(active = 1).filter(**data_dict).first()
    # print("用户",uesr_object)
    #没有值表示登录失败
    if not uesr_object:
    #不正确依然在原来的页面
        form.add_error("password","密码错误") #人为在每个字段下面加错误实现：错误展示在特定文本框下面
        return render(request, "login.html",{"error":"用户名或者密码错误","form":form})
    else:#登录成功 数据库查到的用户信息写入session
        # 键uesr_info = 用户类型role,名字 id号 配置好数据会自动加入rides
        request.session[settings.NB_SESSIONKET]={"role":mappings[role],"name":uesr_object.username,"id":uesr_object.id}
        #登录成功后重定向到http://localhost:8000/level/list/页面

        return redirect("/level/list/")



#短信登录函数
def sms_login(request):
    if request.method == "GET":
        form = account_form.SmsloginForm()
        return render(request, "sms_login.html",{"form":form})

    #1 post请求 手机号验证 角色 短信验证码格式校验
    form = account_form.SmsloginForm(data=request.POST)
    res = BaseResponse()
    if not form.is_valid():
        res.detail = form.errors
        return JsonResponse(res.dict,json_dumps_params = {"ensure_ascii":False})
    #2 获取form验证通过的手机、验证码 角色
    # code = form.cleaned_data.get("code")
    mobile = form.cleaned_data.get("mobile")
    role = form.cleaned_data.get("role")
    #3code验证  获取redis编码 redi获取的是字节 需要decode("utf-8") 【代码优化到SmsloginForm——clean_code】
    # conn = get_redis_connection("default")
    # cache_code = conn.get(mobile)
    # if not cache_code:
    #     res.detail = {"code":["验证码失效或未发送"]} # 需要放在什么输入框的id属性；【提示内容】
    #     return JsonResponse(res.dict, json_dumps_params={"ensure_ascii": False})
    # if code != cache_code.decode("utf-8"):
    #     res.detail = {"code": ["验证码错误"]}
    #     return JsonResponse(res.dict, json_dumps_params={"ensure_ascii": False})
    # 4在数据库判断手机号是否存在 不存在就不能登录
    if role == "1":  # 管理员
        uesr_object = models.Administrator.objects.filter(active=1,mobile=mobile).first()
    elif role == "2":  # 用户
        uesr_object = models.Customer.objects.filter(active=1,mobile=mobile).first()
    if not uesr_object:
        res.detail = {"mobile": ["手机号不存在"]}
        return JsonResponse(res.dict, json_dumps_params={"ensure_ascii": False})
    #5登录成功用户信息写入session
    mappings = {"1": "ADMIN", "2": "CUSTOMER"}
    request.session[settings.NB_SESSIONKET] = {"role": mappings[role], "name": uesr_object.username, "id": uesr_object.id}
    res.status = True
    res.data = settings.LOGIN_HOME #登录成功跳转地址
    return JsonResponse(res.dict)


# 发送短信
def sms_send(request):
    res = BaseResponse()
    print("post",request.POST)
    #1 校验手机号格式 角色 使用Form的校验功能
    form = account_form.MobileForm(data=request.POST)
    # 校验失败
    if not form.is_valid():
        print("校验失败")
        res.detail = form.errors
        # return JsonResponse({
        #     "status":False, #请求失败
        #     "detail":form.errors, #失败提示
        # },json_dumps_params = {"ensure_ascii":False} #json 不转换ascii码 以中文形式显示
        # )
        #以上代码的类形式写法 res.dict 返回{"status":False, #请求失败，"detail":form.errors, #失败提示}
        return JsonResponse(res.dict,json_dumps_params = {"ensure_ascii":False} #json 不转换ascii码 以中文形式显示
        )
    #2 去数据库验证手机号存在(代码移植优化到了MobileForm的clean_mobile函数）
    # role = form.cleaned_data.get("role")
    mobile = form.cleaned_data["mobile"]
    # if role == "1":  # 管理员
    #     uesr_object = models.Administrator.objects.filter(active=1,mobile=mobile).exists() #exists是否存在
    # elif role == "2":  # 用户
    #     uesr_object = models.Customer.objects.filter(active=1,mobile=mobile).exists()
    # if not uesr_object:
    #     res.detail = {"mobile": ["手机号不存在"]}
    #     return JsonResponse(res.dict, json_dumps_params={"ensure_ascii": False})

    #2 生成短信验证码
    code = str(get_code(4))
    #3 容联云发送短信
    print("发送手机号",mobile)
    is_success = send_sms(
        mobile=mobile,  # 这个手机号必须在你在容联云中填写的那个3个测试手机号中
        datas=(code, 1),  # 元组的第一个参数是4位的验证码,注意免费测试的只支持发送4位的验证码，不支持6位的，第二个参数是短信模板中替换为：请于{2}分钟内正确输入
        tid=1  # 这个模板id目前测试阶段固定为1
    )
    if is_success == True:
        # 4 成功后把手机号与验证码保存在redis 便于校验
        conn = get_redis_connection("default")
        conn.set(mobile, code, ex=60)
        redis_value = conn.get(mobile)
        print("在redis存的code",redis_value)
        res.status = True
        return JsonResponse(res.dict)  # 请求成功
    else:
        res.detail = {"code":[is_success]}
        return JsonResponse(res.dict, json_dumps_params={"ensure_ascii": False}  # json 不转换ascii码 以中文形式显示
        )





#退出登录方法
def logout(request):
    #清除session内容
    request.session.clear()
    #恢复到登录页面
    return redirect(settings.NB_LOGIN_URL)

# 用户登录后显示的第一个界面
def homes(request):
    return render(request, "home.html")

def user_list(request):
    return render(request, "user.html")



# 订单管理
def order_list(request):
    return render(request, "order.html")



def order_list_add(request):
    return render(request, "order_add.html")